package threadcommunication;

import java.util.ArrayList;
import java.util.List;

/**
 * 等待wait的条件发生变化
 */
public class Demo_04 {
    public static void main(String[] args) throws InterruptedException {
        String lock = new String("");
        Add add = new Add(lock);
        Subtract subtract = new Subtract(lock);
        TheadSubtract theadSubtract = new TheadSubtract(subtract);
        theadSubtract.setName("theadSubtract");
        theadSubtract.start();
        TheadSubtract theadSubtract2 = new TheadSubtract(subtract);
        theadSubtract2.setName("theadSubtract2");
        theadSubtract2.start();
        Thread.sleep(1000);
        ThreadAdd threadAdd = new ThreadAdd(add);
        threadAdd.setName("threadAdd");
        threadAdd.start();

    }
}

class Add {
    private String lock;

    public Add(String lock) {
        this.lock = lock;
    }

    public void add() {
        synchronized (lock) {
            ValueObject.list.add("anything");
            lock.notifyAll();
        }
    }
}

class Subtract {
    private String lock;

    public Subtract(String lock) {
        this.lock = lock;
    }

    public void subtract() {
        try{
            synchronized (lock){
                while(ValueObject.list.size() == 0) {
                    if (ValueObject.list.size() == 0) {
                        System.out.println("wait begin ThreadName=" + Thread.currentThread().getName());
                        lock.wait();
                        System.out.println("wait end ThreadName=" + Thread.currentThread().getName());
                    }

                }
                ValueObject.list.remove(0);
                System.out.println("list size=" + ValueObject.list.size());
            }
        }catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class ValueObject {
    public static List list = new ArrayList<>();
}

class ThreadAdd extends Thread {
    private Add p;

    public ThreadAdd(Add p) {
        this.p = p;
    }

    @Override
    public  void run() {
        p.add();
    }
}

class TheadSubtract extends Thread {
    private Subtract t;

    public TheadSubtract(Subtract t) {
        this.t = t;
    }

    @Override
    public void run() {
        t.subtract();
    }
}